/**
 * @file Implements EventSet.
 * @author Zmei Zelen <zmei.zelen@gmail.com>
 */


/*
 * A GameLoop object.
 * 
 * @constructor
 * @returns {GameLoop}
 */
function GameLoop() {        
    this.on = new EventSet();      
}


GameLoop.prototype.requestAnimationFrame = 
            (window.requestAnimationFrame
            || window.mozRequestAnimationFrame
            || window.webkitRequestAnimationFrame
            || window.msRequestAnimationFrame
            || function (callback) { return setTimeout(callback, 16); }
            ).bind(window);


GameLoop.prototype.start = function () {
    if (this.clock === undefined) {        
        this.time = (new Date()).getTime();
        this.clock = this.requestAnimationFrame(this.loop.bind(this));
    }
};


GameLoop.prototype.stop = function () {
    if (this.clock !== undefined) {
        clearTimeout(this.clock);
        delete this.clock;
    }
};


GameLoop.prototype.loop = function () {      
    var now = (new Date()).getTime(),
        delta = now - this.time;
    this.time = now;   
        
    this.on.events.each((function (step) {
        step.call(delta, now);
        return true;
    }).bind(this));     

    if (this.clock !== undefined) {
        this.clock = this.requestAnimationFrame(this.loop.bind(this));        
    }    
};


GameLoop.prototype.isRunning = function() {
    return Boolean(this.clock);
};